﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using VitCode.ObjectResolutionHelper;

namespace VitCode.ObjectSettingApp
{
    public class MappingSettingHelper : BaseHelper
    {
        public string GetClassContext(Type objType,string assName,string dbKeyProName)
        {
            m_Checker.CheckClass(objType);
            var keyProInfo = objType.GetProperty(dbKeyProName);
            if(keyProInfo == null)
            {
                keyProInfo = objType.GetProperty(BaseDataKeyInfo.ID);
                if (keyProInfo != null) dbKeyProName = keyProInfo.Name;
            }
            if (objType.IsAbstract) return null;
            var tableName = assName.Replace(".", "_") + "_" + objType.Name;
            PropertyInfo[] pros = LookUpClassHelper.GetPros(objType);
            var sb = new StringBuilder();
            NameValueCollection nvcMap = GetDbTypeMapping();
            var generatorClass = "guid";
            var defaultVal = "00000000-0000-0000-0000-000000000000";
            if (keyProInfo.PropertyType == typeof(int))
            {
                generatorClass = "identity";
                defaultVal = "0";
            }
            sb.Append(
                "\t<class name=\""+objType.Name+"\" dynamic-update=\"true\" dynamic-insert=\"true\" lazy=\"true\"  table='"+tableName+"'>\r\n" +
                "\t\t<id column=\"" + dbKeyProName + "\" name=\"" + dbKeyProName + "\" type=\""+keyProInfo.PropertyType.Name+"\" unsaved-value=\""+defaultVal+"\">\r\n" +
                "\t\t\t<generator class=\""+generatorClass+"\"></generator>\r\n" +
                "\t\t</id>\r\n");
            
            foreach (PropertyInfo p in pros)
            {
                if (p.Name == dbKeyProName) continue;
                var str = GetProContext(p, nvcMap);
                if(!string.IsNullOrEmpty(str))
                    sb.Append(str + "\r\n");
            }

            sb.Append("\t</class>");
            return sb.ToString();
        }

        private string GetProContext(PropertyInfo pro, NameValueCollection nvcTypeMapping)
        {
            if (pro.Name == ID) return "";
            
            var colName = pro.Name;
            var val="";
            var proType = pro.PropertyType;
            if (pro.PropertyType.Name.ToLower().StartsWith("nullable"))
            {
                proType = Nullable.GetUnderlyingType(pro.PropertyType);
            }
            var dbTypeName = nvcTypeMapping.Get(proType.ToString());
            if (string.IsNullOrEmpty(dbTypeName))
            {
                    colName += "Id";
                    var hClassName = pro.PropertyType+ ",";
                    var AssName = pro.PropertyType.Assembly.ToString();
                    AssName = AssName.Substring(0, AssName.IndexOf(","));
                    hClassName += AssName;
                    val = "\t\t<many-to-one class=\""+hClassName+"\" name=\""+pro.Name+"\" column=\""+colName+"\" not-found=\"ignore\"></many-to-one>";
            }
            else
            {
                val = "\t\t<property name=\""+pro.Name+"\" type=\""+proType.Name+"\"></property>";
            }
            return val;
        }
    }
}
